/*
 * VHStandingsGrid.java
 * Created on 28 juin 2009
 *
 * VirtualHockey Internet Platform
 * http://code.google.com/p/virtualhockey/
 *
 * Copyright (c) 2005-2009, Jens and Jan Janke (VirtualHockey Project)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */

package com.hockeo.vhweb.client.ui.widget;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.grid.RowNumberer;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.i18n.client.NumberFormat;
import com.hockeo.vhweb.client.VHMain;
import com.hockeo.vhweb.client.mvc.VHController;
import com.hockeo.vhweb.client.res.VHResConstants;
import com.hockeo.vhweb.client.rpc.VHRpcResultReceiver;
import com.hockeo.vhweb.client.ui.menu.VHClubInfoContextMenu;
import com.hockeo.vhweb.client.ui.menu.VHGridContextMenu;
import com.hockeo.vhweb.client.utils.VHJsData;

/**
 * Special grid displaying the standings of round robin contest elements.
 *
 * @version $Id$
 * @author janjanke
 */
public class VHStandingsGrid extends LayoutContainer implements VHRpcResultReceiver<List<VHJsData>>
{
  public static final int HEIGHT_HEADER = 26;
  public static final int HEIGHT_TEAM   = 24;

  public enum DisplayType
  {
    STANDARD, ETERNAL, HISTORY;
  }

  private final VHGridContextMenu   d_ctxmenu;
  private final DisplayType         d_displayType;
  private final String              d_strElementId;
  private final ListStore<VHJsData> d_store;
  private Grid<VHJsData>            d_grid;

  /**
   * Builds a new standings grid.
   *
   * @param displayType the type of grid to build
   */
  public VHStandingsGrid( VHController controller, DisplayType displayType )
  {
    this( controller, displayType, null );
  }

  /**
   * Builds a new standings grid.
   *
   * @param displayType the type of grid to build
   * @param strElementId the ID of the element for which data should be shown in the grid
   *          (may be null if data is passed in using {@link #setRpcData(List, String)}).
   */
  public VHStandingsGrid( VHController controller, DisplayType displayType, String strElementId )
  {
    d_displayType = displayType;
    d_strElementId = strElementId;
    d_store = createStore();

    buildGrid();
    setLayout( new FitLayout() );
    add( d_grid );

    d_ctxmenu = new VHClubInfoContextMenu( controller, d_grid, "club_" );
  }

  /**
   * Creates the store to be used for backing the grid.
   */
  protected ListStore<VHJsData> createStore()
  {
    return new ListStore<VHJsData>();
  }

  public void setRpcData( List<VHJsData> result, String strPurpose )
  {
    d_store.removeAll();
    d_store.add( result );
    d_store.sort( "rank", SortDir.ASC );
  }

  /**
   * Returns the ideal minimum height in pixels that should be reserved to view this grid
   * without showing scroll bars. Be aware, that this method does not return anything
   * useful unless some data has been loaded into the underlying store.
   */
  public int getMinimumHeight()
  {
    return HEIGHT_HEADER + d_store.getCount() * HEIGHT_TEAM;
  }

  protected final String getElementId()
  {
    return d_strElementId;
  }

  protected final ListStore<VHJsData> getStore()
  {
    return d_store;
  }

  protected final Grid<VHJsData> getGrid()
  {
    return d_grid;
  }

  private void buildGrid()
  {
    final NumberFormat fmtGoalsAccount = NumberFormat.getFormat( "0.0" );
    final NumberFormat fmtGoalsDiff = NumberFormat.getFormat( "+#;-#" );
    GridCellRenderer<VHJsData> renderer = new GridCellRenderer<VHJsData>() {
      public String render( VHJsData data, String strProperty, ColumnData config, int rowIndex, int colIndex,
          ListStore<VHJsData> store, Grid<VHJsData> grid )
      {
        config.css = data.getString( "rankType" );

        if ( strProperty.equals( "rankTendency" ) )
          return "<img src='images/picto/rank_" + data.getString( strProperty ).toLowerCase() + ".gif'/>";
        else if ( strProperty.equals( "rankType" ) )
        {
          String strType = data.getString( strProperty );
          String strImg;

          if ( strType.equals( "QUALIFIED_EU1" ) )
            strImg = "rank_eu1.png";
          else if ( strType.equals( "QUALIFIED_EU2" ) )
            strImg = "rank_eu2.png";
          else if ( strType.equals( "MIDFIELD" ) )
            strImg = "rank_midfield.gif";
          else if ( strType.equals( "RELEGATED" ) )
            strImg = "rank_relegated.gif";
          else
            strImg = "rank_promoted.gif";

          return "<img src='images/picto/" + strImg + "'/>";
        }
        else if ( strProperty.equals( "club_country" ) )
          return "<img src='images/flags/16x16/" + data.getString( strProperty ) + ".png'/>";
        else if ( strProperty.equals( "pointsPercentage" ) )
          return fmtGoalsAccount.format( data.getDouble( strProperty ) * 100.0 );
        else if ( strProperty.equals( "remainingGoals" ) )
          return fmtGoalsAccount.format( data.getDouble( strProperty ) );
        else if ( strProperty.equals( "goalsDiff" ) )
          return fmtGoalsDiff.format( data.getInt( strProperty ) );

        return String.valueOf( data.get( strProperty ) );
      }
    };

    // Column definitions
    //
    VHResConstants constants = VHMain.getConstants();
    ArrayList<ColumnConfig> listCols = new ArrayList<ColumnConfig>();
    ColumnConfig col;

    RowNumberer rowNumberer = new RowNumberer();
    listCols.add( rowNumberer );

    col = new ColumnConfig();
    col.setId( "rank" );
    col.setHeader( constants.rankAbbrev() );
    col.setToolTip( constants.rank() );
    col.setWidth( 28 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setResizable( false );
    listCols.add( col );

    if ( d_displayType != DisplayType.ETERNAL )
    {
      col = new ColumnConfig();
      col.setId( "rankType" );
      col.setHeader( constants.rankTypeAbbrev() );
      col.setToolTip( constants.rankType() );
      col.setWidth( 26 );
      col.setRenderer( renderer );
      col.setAlignment( HorizontalAlignment.CENTER );
      col.setResizable( false );
      listCols.add( col );
    }

    if ( d_displayType == DisplayType.STANDARD )
    {
      col = new ColumnConfig();
      col.setId( "rankTendency" );
      col.setHeader( constants.rankTendencyAbbrev() );
      col.setToolTip( constants.rankTendency() );
      col.setWidth( 26 );
      col.setRenderer( renderer );
      col.setAlignment( HorizontalAlignment.CENTER );
      col.setResizable( false );
      listCols.add( col );
    }

    col = new ColumnConfig();
    col.setId( "club_country" );
    col.setHeader( constants.countryAbbrev() );
    col.setToolTip( constants.country() );
    col.setWidth( 26 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.CENTER );
    col.setResizable( false );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "club_name" );
    col.setHeader( constants.clubName() );
    col.setWidth( 200 );
    col.setRenderer( renderer );
    listCols.add( col );

    if ( d_displayType == DisplayType.ETERNAL )
    {
      col = new ColumnConfig();
      col.setId( "numSeasons" );
      col.setHeader( constants.numSeasonsAbbrev() );
      col.setToolTip( constants.numSeasons() );
      col.setWidth( 30 );
      col.setRenderer( renderer );
      col.setAlignment( HorizontalAlignment.RIGHT );
      listCols.add( col );
    }

    col = new ColumnConfig();
    col.setId( "numMatches" );
    col.setHeader( constants.numMatchesAbbrev() );
    col.setToolTip( constants.numMatches() );
    col.setWidth( 30 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numPoints" );
    col.setHeader( constants.numPointsAbbrev() );
    col.setToolTip( constants.numPoints() );
    col.setWidth( 30 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numWins" );
    col.setHeader( constants.numWinsAbbrev() );
    col.setToolTip( constants.numWins() );
    col.setWidth( 30 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numWinsOT" );
    col.setHeader( constants.numWinsOtAbbrev() );
    col.setToolTip( constants.numWinsOt() );
    col.setWidth( 30 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numLossesOT" );
    col.setHeader( constants.numLossesOtAbbrev() );
    col.setToolTip( constants.numLossesOt() );
    col.setWidth( 30 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numLosses" );
    col.setHeader( constants.numLossesAbbrev() );
    col.setToolTip( constants.numLosses() );
    col.setWidth( 30 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numGoalsFor" );
    col.setHeader( constants.numGoalsForAbbrev() );
    col.setToolTip( constants.numGoalsFor() );
    col.setWidth( 30 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numGoalsAgainst" );
    col.setHeader( constants.numGoalsAgainstAbbrev() );
    col.setToolTip( constants.numGoalsAgainst() );
    col.setWidth( 30 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "goalsDiff" );
    col.setHeader( constants.goalsDiffAbbrev() );
    col.setToolTip( constants.goalsDiff() );
    col.setWidth( 30 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "pointsPercentage" );
    col.setHeader( constants.pointsPctAbbrev() );
    col.setToolTip( constants.pointsPct() );
    col.setWidth( 40 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    listCols.add( col );

    if ( d_displayType == DisplayType.STANDARD )
    {
      col = new ColumnConfig();
      col.setId( "remainingGoals" );
      col.setHeader( constants.goalsAccountAbbrev() );
      col.setToolTip( constants.goalsAccount() );
      col.setWidth( 40 );
      col.setRenderer( renderer );
      col.setAlignment( HorizontalAlignment.RIGHT );
      listCols.add( col );
    }

    final ColumnModel cm = new ColumnModel( listCols );

    // Grid
    //
    d_grid = new Grid<VHJsData>( d_store, cm );
    d_grid.addPlugin( rowNumberer );

    if ( d_displayType == DisplayType.ETERNAL )
      d_grid.setStripeRows( true );

    d_grid.setBorders( true );
    d_grid.setAutoWidth( true );
  }
}
